package com.example.homeworkrabbitmq.controller;

import com.example.homeworkrabbitmq.entity.Course;
import com.example.homeworkrabbitmq.entity.Order;
import com.example.homeworkrabbitmq.entity.User;
import com.example.homeworkrabbitmq.enums.OrderStatus;
import com.example.homeworkrabbitmq.service.CourseService;
import com.example.homeworkrabbitmq.service.OrderService;
import com.example.homeworkrabbitmq.service.UserService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.MessagePropertiesBuilder;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.Query;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping("/order")
@Slf4j
public class OrderController {
    @Autowired
    private OrderService orderService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @RequestMapping("/createOrder")
    public String createOrder(String username, Integer courseId, Model model){
        /**
         * 生成订单，并保存到到数据库
         */
        Order order = orderService.createOrder(username, courseId);
        String orderNo = order.getOrderNo();
        /**
         * 给业务队列发送消息，传递订单号
         */
        rabbitTemplate.convertAndSend("e.biz","q.biz",new Message(orderNo.getBytes(), MessagePropertiesBuilder.newInstance().build()));
        /**
         * 跳转到支付页面
         */
        model.addAttribute("order",order);
        return "pay";
    }

    @RequestMapping("/payOrder")
    public ModelAndView payOrder(String orderNo) {
        /**
         * 查询订单
         */
        Order order = new Order();
        order.setOrderNo(orderNo);
        order = orderService.findOne(order);
        /**
         * 判断订单状态是否是待支付
         */
        //待支付，进入支付逻辑
        if (order.getOrderStatus() == OrderStatus.TO_BE_PAYED) {
           return paySuccess(order);
        } else {
            return payFail(order);
        }
    }

    /**
     * 支付成功
     * @param order
     * @return
     */
    private ModelAndView paySuccess(Order order){
        ModelAndView mv = new ModelAndView();
       //修改订单状态
        order.setOrderStatus(OrderStatus.PAYED);
        order.setUpdateTime(new Date());
        int i = orderService.updateOrderStatus(order);
        mv.setViewName("paySuccess");
        mv.addObject("order",order);
        return mv;
    }

    /**
     * 支付失败
     * @param order
     * @return
     */
    private ModelAndView payFail(Order order){
        ModelAndView mv = new ModelAndView();
        List<Order> failOrderList = orderService.failOrderList(order.getUser().getUsername());
        //转发到展示失败订单页面
        mv.setViewName("payFail");
        mv.addObject("failOrderList",failOrderList);
        return mv;
    }

    @RabbitListener(queuesToDeclare = @Queue("q.dlx"),ackMode = "MANUAL" )
    public void timeoutListen(@Payload String orderNo,
                              Channel channel,
                              @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException {
        /**
         * 根据订单号查询订单状态是不是未支付，
         * 如果是，将订单状态改为超时
         * 确认死信消息
         */
        //查询订单
        Order order = new Order();
        order.setOrderNo(orderNo);
        order = orderService.findOne(order);
        if(order == null){
            return;
        }
        OrderStatus orderStatus = order.getOrderStatus();
        //判断订单是否已支付处理
        if(orderStatus == OrderStatus.TO_BE_PAYED){
            log.info("修改订单号为{}的订单状态为超时",orderNo);
            //表示超过时间没有支付，修改订单状态为超时
            orderService.timeoutOrder(order.getOrderNo());
        }
        //应答消息
        channel.basicAck(deliveryTag,false);
    }


}
